package com.engine4cloud.tdf.supervision.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.engine4cloud.tdf.admin.api.feign.RemoteDeptService;
import com.engine4cloud.tdf.common.core.constant.SecurityConstants;
import com.engine4cloud.tdf.common.core.constant.enums.AllAuditActionStatusEnum;
import com.engine4cloud.tdf.common.core.constant.enums.AuditBusinessTypeEnum;
import com.engine4cloud.tdf.common.core.constant.enums.BriefAuditActionStatusEnum;
import com.engine4cloud.tdf.common.core.constant.enums.CorFileTypeEnum;
import com.engine4cloud.tdf.common.core.exception.ValidateCodeException;
import com.engine4cloud.tdf.common.core.util.R;
import com.engine4cloud.tdf.common.core.util.RetOps;
import com.engine4cloud.tdf.common.data.web.query.Pages;
import com.engine4cloud.tdf.common.data.web.query.Queries;
import com.engine4cloud.tdf.common.data.web.response.PageInfo;
import com.engine4cloud.tdf.common.security.service.TdfUser;
import com.engine4cloud.tdf.common.security.util.SecurityUtils;
import com.engine4cloud.tdf.supervision.convert.SpHelpConvert;
import com.engine4cloud.tdf.supervision.dto.create.SpAuditActionResultCreateDTO;
import com.engine4cloud.tdf.supervision.dto.create.SpHelpCreateDTO;
import com.engine4cloud.tdf.supervision.dto.query.JzdxFileQueryDTO;
import com.engine4cloud.tdf.supervision.dto.query.SpHelpDepartQueryDTO;
import com.engine4cloud.tdf.supervision.dto.query.SpHelpQueryDTO;
import com.engine4cloud.tdf.supervision.dto.result.JzdxResultDTO;
import com.engine4cloud.tdf.supervision.dto.result.SpHelpResultDTO;
import com.engine4cloud.tdf.supervision.dto.update.SpBriefPreActionUpdateDTO;
import com.engine4cloud.tdf.supervision.dto.update.SpHelpUpdateDTO;
import com.engine4cloud.tdf.supervision.entity.SpHelpEntity;
import com.engine4cloud.tdf.supervision.mapper.SpHelpMapper;
import com.engine4cloud.tdf.supervision.service.JzdxFileService;
import com.engine4cloud.tdf.supervision.service.JzdxService;
import com.engine4cloud.tdf.supervision.service.SpAuditResultService;
import com.engine4cloud.tdf.supervision.service.SpHelpService;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 帮扶申请
 *
 * @author wenjie
 * @date 2024-04-26 14:44:20
 */
@Service
public class SpHelpServiceImpl extends ServiceImpl<SpHelpMapper, SpHelpEntity> implements SpHelpService {
    @Resource
    private JzdxService jzdxService;

    @Resource
    private SpAuditResultService auditResultService;

    @Resource
    private RemoteDeptService remoteDeptService;

    @Resource
    private JzdxFileService fileService;

    @Override
    public PageInfo<SpHelpResultDTO> getPageList(SpHelpQueryDTO dto) {
        IPage<SpHelpResultDTO> page = this.baseMapper.pageList(Pages.page(dto), dto);
        return Pages.convert(page);
    }

    @Override
    public SpHelpResultDTO getById(Long id) {
        SpHelpResultDTO result = SpHelpConvert.INSTANCE.convert(super.getById(id));
        //设置法律文书信息
        this.setInstrumentList(result);
        return result;
    }

    @Override
    public SpHelpResultDTO getByBatch(String batch) {
        return SpHelpConvert.INSTANCE.convert(super.getOne(wrapper(new SpHelpQueryDTO(batch))));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean create(SpHelpCreateDTO dto) {
        JzdxResultDTO dx = Optional.ofNullable(jzdxService.getByCode(dto.getRybh()))
                .orElseThrow(() -> new ValidateCodeException("矫正对象数据不存在"));

        TdfUser user = SecurityUtils.getUser();
        SpHelpEntity entity = SpHelpConvert.INSTANCE.create(dto, user.getTenantId(), BriefAuditActionStatusEnum.CREATE);
        super.save(entity);

        //保存法律文书（附件）信息
        this.saveInstrumentList(dto, entity, user);
        //设置审核信息
        return auditResultService.create(
                new SpAuditActionResultCreateDTO(
                        entity.getRybh(),
                        entity.getLcbh(),
                        "",
                        AuditBusinessTypeEnum.HELP,
                        AllAuditActionStatusEnum.CREATE,
                        user.getUsername(),
                        entity.getTenantId(),
                        user.getDeptId()
                ));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(SpHelpUpdateDTO dto) {
        SpHelpEntity old = Optional.ofNullable(super.getById(dto.getId()))
                .orElseThrow(() -> new ValidateCodeException("数据不存在"));

        TdfUser user = SecurityUtils.getUser();
        super.updateById(SpHelpConvert.INSTANCE.update(dto));
        //更新法律文书信息
        this.updateInstrumentList(dto, old, user);
        return true;
    }

    @Override
    public void changeAction(SpBriefPreActionUpdateDTO dto) {
        SpHelpEntity entity = Optional.ofNullable(this.getOne(wrapper(new SpHelpQueryDTO(dto.getRybh(), dto.getLcbh()))))
                .orElseThrow(() -> new ValidateCodeException("数据不存在"));

        entity.setPreAction(dto.getAction());
        super.updateById(entity);
    }

    @Override
    public PageInfo<SpHelpResultDTO> getDeptPageList(SpHelpDepartQueryDTO dto) {
        R<List<Long>> deptIdRemoteList = remoteDeptService.getDescendantIdList(dto.getDeptId(), SecurityConstants.FROM_IN);
        List<Long> deptIdList = RetOps.of(deptIdRemoteList).getData().filter(CollectionUtils::isNotEmpty)
                .orElseThrow(() -> new ValidateCodeException("没有数据权限!"));

        return Pages.convert(this.baseMapper.deptPageList(Pages.page(dto), dto, deptIdList));
    }

    public void saveInstrumentList(SpHelpCreateDTO dto, SpHelpEntity entity, TdfUser user) {
        fileService.batchSaveFile(new JzdxFileQueryDTO(entity.getRybh(), entity.getLcbh(), CorFileTypeEnum.CORRECTOR_HELP), dto.getInstrumentList(), user);
    }

    private void updateInstrumentList(SpHelpUpdateDTO dto, SpHelpEntity entity, TdfUser user) {
        fileService.batchUpdateFile(new JzdxFileQueryDTO(entity.getRybh(), entity.getLcbh(), CorFileTypeEnum.CORRECTOR_HELP), dto.getInstrumentList(), user);
    }

    private void setInstrumentList(SpHelpResultDTO dto) {
        JzdxFileQueryDTO query = new JzdxFileQueryDTO(dto.getRybh(), dto.getLcbh(), CorFileTypeEnum.CORRECTOR_HELP);
        dto.setInstrumentList(fileService.findList(query));
    }

    private LambdaQueryWrapper<SpHelpEntity> wrapper(SpHelpQueryDTO query) {
        LambdaQueryWrapper<SpHelpEntity> wrapper = Queries.lambda();
        Queries.accept(query.getId(), v -> wrapper.eq(SpHelpEntity::getId, v));
        Queries.accept(query.getRybh(), v -> wrapper.eq(SpHelpEntity::getRybh, v));
        Queries.accept(query.getLcbh(), v -> wrapper.eq(SpHelpEntity::getLcbh, v));
        Queries.accept(query.getPreAction(), v -> wrapper.eq(SpHelpEntity::getPreAction, v));
        return wrapper;
    }
}